package DiffieHellman.TestSM2;

import org.bouncycastle.math.ec.*;
import org.bouncycastle.math.raw.Nat256;
import org.bouncycastle.util.encoders.Hex;

import java.math.BigInteger;
import java.security.SecureRandom;

public class TestSM2Curve extends ECCurve.AbstractFp {
    public static final BigInteger q;
    private static final int SM2P256V1_DEFAULT_COORDS = 2;
    private static final ECFieldElement[] SM2P256V1_AFFINE_ZS;
    protected TestSM2Point infinity = new TestSM2Point(this, (ECFieldElement) null, (ECFieldElement) null);

    public TestSM2Curve() {
        super(q);
        this.a = this.fromBigInteger(new BigInteger(1, Hex.decodeStrict("787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498")));
        this.b = this.fromBigInteger(new BigInteger(1, Hex.decodeStrict("63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A")));
        this.order = new BigInteger(1, Hex.decodeStrict("8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7"));
        this.cofactor = BigInteger.valueOf(1L);
        this.coord = 2;
    }

    protected ECCurve cloneCurve() {
        return new DiffieHellman.TestSM2.TestSM2Curve();
    }

    public boolean supportsCoordinateSystem(int var1) {
        switch (var1) {
            case 2:
                return true;
            default:
                return false;
        }
    }

    public BigInteger getQ() {
        return q;
    }

    public int getFieldSize() {
        return q.bitLength();
    }

    public ECFieldElement fromBigInteger(BigInteger var1) {
        return new TestSM2FieldElement(var1);
    }

    protected ECPoint createRawPoint(ECFieldElement var1, ECFieldElement var2) {
        return new TestSM2Point(this, var1, var2);
    }

    protected ECPoint createRawPoint(ECFieldElement var1, ECFieldElement var2, ECFieldElement[] var3) {
        return new TestSM2Point(this, var1, var2, var3);
    }

    public ECPoint getInfinity() {
        return this.infinity;
    }

    public ECLookupTable createCacheSafeLookupTable(ECPoint[] var1, int var2, final int var3) {
        final int[] var5 = new int[var3 * 8 * 2];
        int var6 = 0;

        for (int var7 = 0; var7 < var3; ++var7) {
            ECPoint var8 = var1[var2 + var7];
            Nat256.copy(((TestSM2FieldElement) var8.getRawXCoord()).x, 0, var5, var6);
            var6 += 8;
            Nat256.copy(((TestSM2FieldElement) var8.getRawYCoord()).x, 0, var5, var6);
            var6 += 8;
        }

        return new AbstractECLookupTable() {
            public int getSize() {
                return var3;
            }

            public ECPoint lookup(int var1) {
                int[] var2 = Nat256.create();
                int[] var3x = Nat256.create();
                int var4 = 0;

                for (int var5x = 0; var5x < var3; ++var5x) {
                    int var6 = (var5x ^ var1) - 1 >> 31;

                    for (int var7 = 0; var7 < 8; ++var7) {
                        var2[var7] ^= var5[var4 + var7] & var6;
                        var3x[var7] ^= var5[var4 + 8 + var7] & var6;
                    }

                    var4 += 16;
                }

                return this.createPoint(var2, var3x);
            }

            public ECPoint lookupVar(int var1) {
                int[] var2 = Nat256.create();
                int[] var3x = Nat256.create();
                int var4 = var1 * 8 * 2;

                for (int var5x = 0; var5x < 8; ++var5x) {
                    var2[var5x] = var5[var4 + var5x];
                    var3x[var5x] = var5[var4 + 8 + var5x];
                }

                return this.createPoint(var2, var3x);
            }

            private ECPoint createPoint(int[] var1, int[] var2) {
                return DiffieHellman.TestSM2.TestSM2Curve.this.createRawPoint(new TestSM2FieldElement(var1), new TestSM2FieldElement(var2), SM2P256V1_AFFINE_ZS);
            }
        };
    }

    public ECFieldElement randomFieldElement(SecureRandom var1) {
        int[] var2 = Nat256.create();
        TestSM2Field.random(var1, var2);
        return new TestSM2FieldElement(var2);
    }

    public ECFieldElement randomFieldElementMult(SecureRandom var1) {
        int[] var2 = Nat256.create();
        TestSM2Field.randomMult(var1, var2);
        return new TestSM2FieldElement(var2);
    }

    static {
        q = TestSM2FieldElement.Q;
        SM2P256V1_AFFINE_ZS = new ECFieldElement[]{new TestSM2FieldElement(ECConstants.ONE)};
    }
}
